package com.yc.web.servlets;

import com.google.gson.Gson;
import com.yc.dao.DBHelper;
import com.yc.web.model.JsonModel;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

public abstract class BaseServlet extends HttpServlet {
    protected DBHelper db = new DBHelper();
//    private <T> Method findSetMethod(String methodName, Class<T> c) {
//
//        Method[] ms=c.getDeclaredMethods();
//        for(   Method m:ms){
//            if(  methodName.equals( m.getName() )){
//                return m;
//            }
//        }
//        return null;
//    }
protected <T> T parseObjectFromRequest(HttpServletRequest request, Class<T> cls) throws InstantiationException, IllegalAccessException, InvocationTargetException, ParseException {
    // 创建T
    T t = cls.newInstance();

    // 取出request中所有的参数
    Map<String, String[]> parameterMap = request.getParameterMap();
    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue()[0]; // 只考虑一个值的情况。
        if (value == null) {
            continue;
        }

        // 找到对应的set方法
        String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);
        Method setMethod = findSetMethod(methodName, cls);
        if (setMethod == null) {
            continue;
        }

        // 获取set方法的参数类型
        Class<?> parameterTypeClass = setMethod.getParameterTypes()[0];

        try {
            // 根据参数类型进行类型转换和调用
            if (parameterTypeClass == int.class || parameterTypeClass == Integer.class) {
                int p = Integer.parseInt(value);
                setMethod.invoke(t, p);
            } else if (parameterTypeClass == float.class || parameterTypeClass == Float.class) {
                float p = Float.parseFloat(value);
                setMethod.invoke(t, p);
            } else if (parameterTypeClass == double.class || parameterTypeClass == Double.class) {
                double p = Double.parseDouble(value);
                setMethod.invoke(t, p);
            } else if (parameterTypeClass == byte.class || parameterTypeClass == Byte.class) {
                byte p = Byte.parseByte(value);
                setMethod.invoke(t, p);
            } else if (parameterTypeClass == long.class || parameterTypeClass == Long.class) {
                long p = Long.parseLong(value);
                setMethod.invoke(t, p);
            } else if (parameterTypeClass == short.class || parameterTypeClass == Short.class) {
                short p = Short.parseShort(value);
                setMethod.invoke(t, p);
            }else if (parameterTypeClass == Date.class) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = null;

                // 检查 value 是否为空或者 null
                if (value != null && !value.isEmpty()) {
                    try {
                        date = dateFormat.parse(value);
                    } catch (ParseException e) {
                        // 可以选择在解析失败时处理异常，比如记录日志或者抛出自定义异常
                        e.printStackTrace(); // 示例中简单打印异常堆栈信息
                    }
                }

                // 将 date 设置到对象 t 的属性上
                try {
                    setMethod.invoke(t, date);
                } catch (IllegalAccessException | InvocationTargetException e) {
                    // 处理 set 方法调用时的异常
                    e.printStackTrace(); // 示例中简单打印异常堆栈信息
                }
            }

            else {
                // 默认情况下直接调用set方法
                setMethod.invoke(t, value);
            }
        } catch (NumberFormatException e) {
            // 处理类型转换异常
            e.printStackTrace(); // 可以根据实际情况处理异常
        }
    }
    return t;
}

    // 辅助方法：根据方法名和类找到对应的set方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String op = req.getParameter("op"); //op=regFile
        JsonModel jm = new JsonModel(); //用来保存要运行后的信息  并  返回到前端
        try {
            if (op == null || "".equals(op)) {
                // out.println( "{code:0,error:'没有op参数'}"  );
                jm.setCode(0);
                jm.setError("op参数不能为空..");
                writeJson(jm,resp);
                return;
            }
            ///        反 射
            Method[] methods  = this.getClass().getDeclaredMethods();//取子类中的方法
            for (Method m:methods){
                if (  m.getName().equals(  op  )  ) {  // 判断有没有 regFile方法
                    m.invoke(this, req,  resp);//激活对应函数  regFile
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            jm.setCode(0);
            jm.setError(  e.getMessage()  );
            writeJson(jm,resp);

        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        req.setCharacterEncoding("utf-8");
//        resp.setCharacterEncoding("utf-8");  // 响应流的编码
//        resp.setContentType("text/html;charset=utf-8");//将功能移动到CharacterFilter中实现

        super.service(req, resp);
    }

    //*** 后端传数据到前端  关键地方   ***    以json格式传数据到前端
    protected void writeJson(  JsonModel jm , HttpServletResponse resp) throws IOException {
        resp.setContentType("text/json;charset=utf-8");
        PrintWriter out = resp.getWriter();
        Gson g = new Gson();
        out.println(  g.toJson(  jm  )); ///后端 把 运行情况 以json类型传出到前端
        out.flush();
        out.close();
    }
    protected void writeObiectJson(  Object obj , HttpServletResponse resp) throws IOException {
        resp.setContentType("text/json;charset=utf-8");
        PrintWriter out = resp.getWriter();
        Gson g = new Gson();
        out.println(  g.toJson(  obj  )); ///后端 把 运行情况 以json类型传出到前端
        out.flush();
        out.close();
    }
    private static int getIntParameter(HttpServletRequest request, String paramName, int defaultValue) {
        String paramValue = request.getParameter(paramName);
        if (paramValue != null) {
            try {
                return Integer.parseInt(paramValue);
            } catch (NumberFormatException e) {
                // 处理异常情况，比如参数不是合法的整数
            }
        }
        return defaultValue;
    }
    //自己写的类


    private Method findSetMethod(String methodName, Class<?> cls) {
        for (Method method : cls.getMethods()) {
            if (method.getName().equals(methodName) && method.getParameterCount() == 1) {
                return method;
            }
        }
        return null;
    }

}
